defmodule House.BasicData do
  @moduledoc """
  The boundary for the BasicData system.
  """

  import Ecto.{Query, Changeset}, warn: false
  alias House.Repo

  alias House.BasicData.Item

  @doc """
  Returns the list of items.

  ## Examples

      iex> list_items()
      [%Item{}, ...]

  """
  def list_items do
    Repo.all(Item)
  end

  @doc """
  Gets a single item.

  Raises `Ecto.NoResultsError` if the Item does not exist.

  ## Examples

      iex> get_item!(123)
      %Item{}

      iex> get_item!(456)
      ** (Ecto.NoResultsError)

  """
  def get_item!(id), do: Repo.get!(Item, id)

  @doc """
  Creates a item.

  ## Examples

      iex> create_item(%{field: value})
      {:ok, %Item{}}

      iex> create_item(%{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def create_item(attrs \\ %{}) do
    %Item{}
    |> item_changeset(attrs)
    |> Repo.insert()
  end

  @doc """
  Updates a item.

  ## Examples

      iex> update_item(item, %{field: new_value})
      {:ok, %Item{}}

      iex> update_item(item, %{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def update_item(%Item{} = item, attrs) do
    item
    |> item_changeset(attrs)
    |> Repo.update()
  end

  @doc """
  Deletes a Item.

  ## Examples

      iex> delete_item(item)
      {:ok, %Item{}}

      iex> delete_item(item)
      {:error, %Ecto.Changeset{}}

  """
  def delete_item(%Item{} = item) do
    Repo.delete(item)
  end

  @doc """
  Returns an `%Ecto.Changeset{}` for tracking item changes.

  ## Examples

      iex> change_item(item)
      %Ecto.Changeset{source: %Item{}}

  """
  def change_item(%Item{} = item) do
    item_changeset(item, %{})
  end

  defp item_changeset(%Item{} = item, attrs) do
    item
    |> cast(attrs, [:address, :gps, :name, :year, :floor, :service, :summary, :stop, :around, :sunshine, :noise, :kitchen, :fitment, :terrace, :bedroom, :livingroom, :traffic, :heating, :investment, :license, :loan, :price, :area, :fee])
    |> validate_required([:name
      # , :address, :gps, :name, :year, :floor, :service, :summary, :stop, :around, :sunshine, :noise, :kitchen, :fitment, :terrace, :bedroom, :livingroom, :traffic, :heating, :investment, :license, :loan
    ])
  end

  alias House.BasicData.Photo

  @doc """
  Returns the list of photos.

  ## Examples

      iex> list_photos()
      [%Photo{}, ...]

  """
  def list_photos(item_id \\ 0) do
    case item_id do
      0 -> Repo.all(Photo)
      _ ->
        (from p in Photo,
          where: p.item_id == ^item_id)
        |> Repo.all
    end
  end

  @doc """
  Gets a single photo.

  Raises `Ecto.NoResultsError` if the Photo does not exist.

  ## Examples

      iex> get_photo!(123)
      %Photo{}

      iex> get_photo!(456)
      ** (Ecto.NoResultsError)

  """
  def get_photo!(id), do: Repo.get!(Photo, id)

  @doc """
  Creates a photo.

  ## Examples

      iex> create_photo(item_id, %{field: value})
      {:ok, %Photo{}}

      iex> create_photo(item_id, %{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def create_photo(item_id, attrs \\ %{}) do
    %Photo{item_id: item_id}
    |> photo_changeset(attrs)
    |> Repo.insert()
  end

  @doc """
  Updates a photo.

  ## Examples

      iex> update_photo(photo, %{field: new_value})
      {:ok, %Photo{}}

      iex> update_photo(photo, %{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def update_photo(%Photo{} = photo, attrs) do
    photo
    |> photo_changeset(attrs)
    |> Repo.update()
  end

  @doc """
  Deletes a Photo.

  ## Examples

      iex> delete_photo(photo)
      {:ok, %Photo{}}

      iex> delete_photo(photo)
      {:error, %Ecto.Changeset{}}

  """
  def delete_photo(%Photo{} = photo) do
    Repo.delete(photo)
  end

  @doc """
  Returns an `%Ecto.Changeset{}` for tracking photo changes.

  ## Examples

      iex> change_photo(photo)
      %Ecto.Changeset{source: %Photo{}}

  """
  def change_photo(%Photo{} = photo) do
    photo_changeset(photo, %{})
  end

  defp photo_changeset(%Photo{} = photo, attrs) do
    photo
    |> cast(attrs, [:kind, :url])
    |> validate_required([:kind, :url])
  end
end
